package user.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.Transferable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.border.Border;

import system.activity.MainListener;
import system.util.ReportUtil;
import system.util.SettingsUtil;
import system.util.TransferableImage;
import user.activity.PicturePanel;

public class PicturePanelImpl extends javax.swing.JPanel implements
		PicturePanel, ClipboardOwner {

	protected static final int WHEEL = 3;
	private BufferedImage originalImage = null;
	private Image image = null;
	private MainListener listener;
	private JLabel picLabel;
	private JLabel selectionLabel;

	private int scrollX;
	private int scrollY;
	private int xStart;
	private int yStart;
	private int xEnd;
	private int yEnd;
	private double currentZoom = 1;
	private double zoomStep = 1.2;
	JPopupMenu menu;
	protected boolean leftButtonPressed;

	public PicturePanelImpl() {
		super();
		initComponents();

	}

	public PicturePanelImpl(MainListener listener) {
		this.listener = listener;
		initComponents();
	}

	private void initComponents() {
		this.setLayout(null);
		final Border border = BorderFactory.createEtchedBorder(Color.white,
				new Color(178, 178, 178));
		this.setBorder(border);
		initMenu();
	}

	private void initMenu() {
		menu = new JPopupMenu();
		JMenuItem itemSave = new JMenuItem("Сохранить");
		menu.add(itemSave);
		itemSave.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				BufferedImage img = getSelectedPart();
				JFileChooser fileChooser = new JFileChooser();
				try {
					if (new File(SettingsUtil.getDefaultFolder()) != null)
						fileChooser.setCurrentDirectory(new File(SettingsUtil
								.getDefaultFolder()));
				} catch (Exception exc) {
					exc.printStackTrace();
				}
				int ret = fileChooser.showDialog(null, "Сохранить изображение");
				if (ret == JFileChooser.APPROVE_OPTION) {
					File file = fileChooser.getSelectedFile();
					ReportUtil.saveImage(img, file.getAbsolutePath());
					fileChooser.setCurrentDirectory(file);
				}
			}
		});

		JMenuItem itemCopy = new JMenuItem("Копировать");
		menu.add(itemCopy);
		itemCopy.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				BufferedImage img = getSelectedPart();
				TransferableImage trans = new TransferableImage(img);
				Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
				c.setContents(trans, getPicturePanelImpl());
			}

		});
	}

	@Override
	public void paint(Graphics g) {
		if (image != null) {
			g.drawImage(image, 0, 0, null);
		}
		super.paintChildren(g);
		super.paintBorder(g);
	}

	@Override
	public BufferedImage getImage() {
		return originalImage;
	}

	@Override
	public void setImage(BufferedImage image) {
		this.originalImage = image;
		this.removeAll();
		picLabel = new JLabel(new ImageIcon(this.originalImage));
		picLabel.setBounds(0, 0, originalImage.getWidth(),
				originalImage.getHeight());
		add(picLabel);
		initMouseAdapter();
		Dimension dim = new Dimension();
		dim.setSize(image.getWidth(), image.getHeight());
		setPreferredSize(dim);
		setSize(image.getWidth(), image.getHeight());
	}

	private void initMouseAdapter() {
		MouseAdapter mouseAdapter = new java.awt.event.MouseAdapter() {

			public void mousePressed(MouseEvent e) {
				leftButtonPressed = e.getButton() == 1;
				xStart = e.getX();
				yStart = e.getY();
				if (e.getButton() == 3) {
					menu.show(e.getComponent(), e.getX(), e.getY());
				}
				if (e.getButton() != 3 && selectionLabel != null) {
					remove(selectionLabel);
				}
				repaint();
				show();
				if (listener != null) {
					listener.needRepaint();
				}
			};

			@Override
			public void mouseDragged(MouseEvent e) {
				if (leftButtonPressed) {
					if (selectionLabel != null) {
						remove(selectionLabel);
					}
					xEnd = e.getX() > picLabel.getWidth() ? picLabel.getWidth()
							: e.getX();
					yEnd = e.getY() > picLabel.getHeight() ? picLabel
							.getHeight() : e.getY();
					selectionLabel = new JLabel(new ImageIcon(
							new BufferedImage(Math.abs(xEnd - xStart),
									Math.abs(yEnd - yStart),
									BufferedImage.TYPE_INT_ARGB)));
					int x = (xEnd > xStart ? xStart - getX() : xStart - getX()
							- Math.abs(xEnd - xStart))
							- scrollX;
					int y = (yEnd > yStart ? yStart - getY() : yStart - getY()
							- Math.abs(yEnd - yStart))
							- scrollY;
					selectionLabel.setBounds(x, y, Math.abs(xEnd - xStart),
							Math.abs(yEnd - yStart));
					add(selectionLabel);
					selectionLabel.setBorder(BorderFactory.createEtchedBorder(
							Color.yellow, new Color(178, 178, 178)));
					setComponentZOrder(selectionLabel, 0);
					listener.needRepaint();
				}
			}

		};
		picLabel.addMouseListener(mouseAdapter);
		picLabel.addMouseMotionListener(mouseAdapter);
	}

	@Override
	public void setImageFile(File imageFile) {
		try {
			this.removeAll();
			this.originalImage = ImageIO.read(imageFile);
			picLabel = new JLabel(new ImageIcon(this.originalImage));
			picLabel.setBounds(0, 0, 150, 150);
			add(picLabel);
			this.repaint();
			this.show();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void setPictureSize(int width, int height) {
	}

	@Override
	public void setListener(MainListener listener) {
		this.listener = listener;
	}

	@Override
	public PicturePanelImpl getPanel() {
		return new PicturePanelImpl();
	}

	@Override
	public void addButtons(JPanel buttonsView) {
		System.out.println("addButtons");
		this.add(buttonsView, BorderLayout.EAST);
	}

	@Override
	public double getZoomValue() {
		return currentZoom;
	}

	@Override
	public double zoomIn() {
		this.removeAll();
		currentZoom *= zoomStep;
		return zoomPerform();
	}

	@Override
	public double zoomOut() {
		this.removeAll();
		currentZoom /= zoomStep;
		return zoomPerform();
	}

	private double zoomPerform() {
		picLabel = new JLabel(new ImageIcon(originalImage.getScaledInstance(
				(int) (originalImage.getWidth() * currentZoom),
				(int) (originalImage.getHeight() * currentZoom),
				Image.SCALE_DEFAULT)));
		picLabel.setBounds(0, 0,
				(int) (originalImage.getWidth() * currentZoom),
				(int) (originalImage.getHeight() * currentZoom));
		add(picLabel);
		Dimension dim = new Dimension();
		dim.setSize((int) (originalImage.getWidth() * currentZoom),
				(int) (originalImage.getHeight() * currentZoom));
		setPreferredSize(dim);
		initMouseAdapter();
		/*
		 * repaint(); show(); listener.needRepaint();
		 */
		return currentZoom;
	}

	// setPreferredSize(dim);
	public int getxStart() {
		return xStart;
	}

	public void setxStart(int xStart) {
		this.xStart = xStart;
	}

	public int getyStart() {
		return yStart;
	}

	public void setyStart(int yStart) {
		this.yStart = yStart;
	}

	public int getxEnd() {
		return xEnd;
	}

	public void setxEnd(int xEnd) {
		this.xEnd = xEnd;
	}

	public int getyEnd() {
		return yEnd;
	}

	public void setyEnd(int yEnd) {
		this.yEnd = yEnd;
	}

	public int getScrollX() {
		return scrollX;
	}

	public void setScrollX(int scrollX) {
		this.scrollX = scrollX;
	}

	public int getScrollY() {
		return scrollY;
	}

	public void setScrollY(int scrollY) {
		this.scrollY = scrollY;
	}

	private PicturePanelImpl getPicturePanelImpl() {
		return this;
	}

	@Override
	public void lostOwnership(Clipboard clipboard, Transferable contents) {
		// TODO Auto-generated method stub
	}

	private BufferedImage getSelectedPart() {
		BufferedImage img;
		if (selectionLabel == null || selectionLabel.getWidth() == 0
				|| selectionLabel.getHeight() == 0) {
			img = originalImage;
		} else {
			img = originalImage.getSubimage(
					(int) (selectionLabel.getX() / currentZoom),
					(int) (selectionLabel.getY() / currentZoom),
					(int) (selectionLabel.getWidth() / currentZoom),
					(int) (selectionLabel.getHeight() / currentZoom)); // currentZoom)
		}
		return img;
	}
}